IDEAL
INCLUDE "macros.inc"

JUMPS

IF @Model ne 1
DISPLAY "Ten program wymaga modelu TINY i linkowania do pliku typu COM"
ERR
ELSE

activ_key       =       4EF0h
deactiv_key     =       4AF0h
ident           =       0F0h

IFDEF __CTRL__
??defined       =       1
ELSEIFDEF __ALT__
??defined       =       1
ELSEIFDEF __TYLDA__
??defined       =       1
ELSE
??defined       =       0
ENDIF

IFE ??defined
DISPLAY "Musisz zdefiniowac symbol __TYLDA__, __ALT__ lub __CTRL__"
ERR
ELSE

IFDEF __CTRL__
  __ALT__       EQU
ENDIF

SEGMENT         BIOS    AT 40h
                ORG     17h
keyb_status     db      ?
keyb_status1    db      ?
                ORG     1Ch
keyb_write      dw      ?
ENDS

CODESEG
                ORG     0h
LABEL           code_start      BYTE
                ORG     5Ch
ascii_read      db      18 dup (?)
ascii_write     db      18 dup (?)
jaki_st         db      ?
activ           db      ?
IFDEF __TYLDA__
if_change       db      ?
ENDIF

LABEL           start_rez       BYTE

                STARTUPCODE
                jmp     inicjuj

                ASSUME  cs:@code, ds:BIOS, es:NOTHING, ss:NOTHING

IFDEF __TYLDA__
PROC            klaw    FAR
                push    ds
                push    bx
                mov     bx,BIOS
                mov     ds,bx
                mov     bx,[keyb_write]
                pushf
old_09h         =       dword $ + 1
                call    far 0:0
                cmp     bx,[keyb_write]
                je      @@7
                push    ax
                mov     ax,[bx]
                cmp     ax,activ_key
                jne     @@1
                mov     [activ],0FFh
                jmp     short @@2
        @@1:    cmp     ax,deactiv_key
                jne     @@3
                mov     [activ],0h
        @@2:    mov     [keyb_write],bx
                jmp     short @@6
        @@3:    cmp     [activ],0
                je      @@6
                cmp     ah,41
                je      @@5
                cmp     [if_change],0
                je      @@6
                not     [if_change]
                push    cx
                push    di
                push    es
                mov     cx,18
                mov     di,OFFSET ascii_read
                push    cs
                pop     es
                cld
                repne   scasb
                jne     @@4
                mov     di,18
                sub     di,cx
                xor     ah,ah
                mov     al,[di+ascii_write-1]
                mov     [bx],ax
        @@4:    pop     es
                pop     di
                pop     cx
                jmp     short @@6
        @@5:    xor     [if_change],0FFh
                jnz     @@2
        @@6:    pop     ax
        @@7:    pop     bx
                pop     ds
                iret
ENDP            klaw
ENDIF

IFDEF __ALT__
PROC            klaw    FAR
                push    ds
                push    bx
                mov     bx,BIOS
                mov     ds,bx
                mov     bx,[keyb_write]
                pushf
old_09h         =       dword $ + 1
                call    far 0:0
IFDEF __CTRL__
                test    [keyb_status1],1
ELSE
                test    [keyb_status1],2
ENDIF
                jnz     @@8
                cmp     bx,[keyb_write]
                je      @@8
                push    ax
                mov     ax,[bx]
                cmp     ax,activ_key
                jne     @@1
                mov     [activ],0FFh
                jmp     short @@2
        @@1:    cmp     ax,deactiv_key
                jne     @@3
                mov     [activ],0h
        @@2:    mov     [keyb_write],bx
                jmp     short @@7
        @@3:    cmp     [activ],0
                je      @@7
                push    es
                push    di
                push    cx
                push    cs
                pop     es
                mov     di,OFFSET ascii_read
                mov     cx,9
                cld
                repne   scasw
                jne     @@6
                mov     di,9
                sub     di,cx
                mov     al,[keyb_status]
                and     al,43h                  ; 01000011b
                jz      @@4
                cmp     al,40h                  ; 01000000b
                jbe     @@5
        @@4:    add     di,9
        @@5:    xor     ah,ah
                mov     al,[di+ascii_write-1]
                mov     [bx],ax
        @@6:    pop     cx
                pop     di
                pop     es
        @@7:    pop     ax
        @@8:    pop     bx
                pop     ds
                iret
ENDP            klaw
ENDIF

                ASSUME  ds:NOTHING

PROC            multiplex       FAR
                sti
                cmp     ah,ident                ; czy pytanie o ten program
                je      @@1
old_2Fh         =       dword $ + 1
                jmp     far 0:0
        @@1:    cmp     al,0                    ; pytanie o status
                jne     @@2
                mov     al,0FFh
                push    cs
                pop     es
        @@2:    iret
ENDP            multiplex

LABEL           end_rez         BYTE

dl_rez          =               end_rez - klaw
diff            =               klaw - start_rez
resident        =               end_rez - diff - code_start

EXTRN   _CType  setargv : PROC
EXTRN   _CType  argc    : WORD
EXTRN   _CType  argv    : DATAPTR

                ASSUME  ds:@data

inicjuj:        mov     ah,09h                  ; copyright info
                mov     dx,OFFSET copyright
                int     21h
                call    setargv                 ; pobierz parametry wywołania
                mov     cx,[argc]               ; liczba parametrów + 1
                dec     cx                      ; liczba parametrów
                jcxz    bad_param               ; brak parametrów -> wyświetl help
                mov     si,[argv]               ; sprawdź parametry wywołania
                xor     dx,dx
argv_loop:
                add     si,2
                mov     bx,[si]
                mov     ax,[bx]
                call    convertax
                cmp     ax,'am'                 ; Mazovia
                jne     @@2
                mov     dl,1
                jmp     argv_loop_end
        @@2:    cmp     ax,'sc'                 ; CSK
                jne     @@3
                mov     dl,2
                jmp     argv_loop_end
        @@3:    cmp     ax,'yc'                 ; Cyfromat
                jne     @@4
                mov     dl,3
                jmp     argv_loop_end
        @@4:    cmp     ax,'hd'                 ; DHN
                jne     @@5
                mov     dl,4
                jmp     argv_loop_end
        @@5:    cmp     ax,'al'                 ; Latin-2
                jne     @@6
                mov     dl,5
                jmp     argv_loop_end
        @@6:    cmp     ax,'ei'                 ; IEA Świerk
                jne     @@7
                mov     dl,6
                jmp     argv_loop_end
        @@7:    cmp     ax,'ol'                 ; LOGIC
                jne     @@8
                mov     dl,7
                jmp     argv_loop_end
        @@8:    cmp     ax,'im'                 ; Microvex
                jne     @@9
                mov     dl,8
                jmp     argv_loop_end
        @@9:    cmp     ax,'si'                 ; ISO Latin-2
                jne     @@10
                mov     dl,9
                jmp     argv_loop_end
        @@10:   cmp     ax,'iw'                 ; Windows 3.1
                jne     @@11
                mov     dl,10
                jmp     argv_loop_end
        @@11:   cmp     ax,'eh'                 ; help
                jne     @@12
                or      dh,1
                jmp     argv_loop_end
        @@12:   cmp     ax,'ts'                 ; status
                jne     @@13
                or      dh,2
                jmp     argv_loop_end
        @@13:   cmp     ax,'do'                 ; odinstaluj
                je      @@14
                cmp     ax,'er'                 ; odinstaluj
                jne     @@15
        @@14:   or      dh,4
                jmp     argv_loop_end
        @@15:   cmp     al,'+'                  ; aktywuj
                jne     @@16
                and     dh,NOT 16
                or      dh,8
                jmp     argv_loop_end
        @@16:   cmp     al,'-'                  ; deaktywuj
                jne     bad_param
                and     dh,NOT 8
                or      dh,16
                jmp     argv_loop_end
bad_param:      mov     dx,100h
                jmp     after_loop
argv_loop_end:  loop    argv_loop
after_loop:     xor     ax,ax
                mov     es,ax
                mov     ah,ident
                int     2Fh
                test    dh,4
                jnz     do_uninst               ; odinstaluj
                or      dl,dl
                jz      skip_inst               ; pomiń instalację
                cmp     al,0FFh
                jne     do_inst                 ; instaluj
                mov     bx,es
                or      bx,bx
                jnz     set_st                  ; zainstalowany
do_inst:        mov     bx,cs                   ; instalujemy
                mov     es,bx                   ; es -> segment docelowy (kod)
                mov     di,offset start_rez     ; początek obszaru rezydentnego
                mov     si,offset klaw          ; początek kodu do relokacji
                mov     cx,dl_rez               ; długość kodu rezydentnego
                shr     cx,1                    ; relokuj
                inc     cx
                rep     movsw
                mov     si,offset ascii_codes
                mov     di,offset ascii_read
                mov     cl,9
                rep     movsw
                mov     [jaki_st],0
                mov     [activ],0
IFDEF __TYLDA__
                mov     [if_change],0
ENDIF
                push    es
                mov     ax,3509h                ; pobierz wektor przerwania 09h
                int     21h
                mov     [word old_09h-diff],bx  ; i zapamiętaj na później
                mov     [word old_09h+2-diff],es
                mov     ax,352Fh                ; pobierz wektor przerwania 2Fh
                int     21h
                mov     [word old_2Fh-diff],bx  ; i zapamiętaj
                mov     [word old_2Fh+2-diff],es
                pop     es
                push    dx
                mov     ax,2509h                ; instaluj obsługę klawiatury
                mov     dx,offset klaw-diff
                int     21h
                mov     ax,252Fh                ; instaluj multiplexor
                mov     dx,offset multiplex-diff
                int     21h
                push    es
                mov     es,[2Ch]
                mov     ah,49h
                int     21h
                pop     es
                pop     dx
                or      dh,32                   ; instaluj rezydentnie
set_st:         cmp     [es:jaki_st],dl         ; ustaw standard
                je      skip_inst               ; już jest
                mov     [es:jaki_st],dl         ; zapamiętaj standard
                mov     ah,dl
                dec     ah
                mov     al,18
                mul     ah
                mov     si,offset mazovia
                add     si,ax                   ; znaki do zapisu
                mov     di,offset ascii_write
                mov     cx,9
                rep     movsw
skip_inst:      test    dh,16
                jz      @@23
                mov     [es:activ],0
        @@23:   test    dh,8
                jz      @@24
                mov     [es:activ],0FFh
        @@24:   test    dh,1
                jz      @@25
                call    print_help
        @@25:   test    dh,2
                jz      @@26
                call    print_status
        @@26:   xor     al,al
                test    dh,32
                jz      exit                    ; normalne zakończenie
                mov     dx,(resident SHR 4) + 1
                mov     ah,31h
                int     21h
exit:           mov     ah,4Ch
                int     21h
do_uninst:      cmp     al,0FFh
                jne     @@29                    ; program jeszcze nie był zainstalowany
                mov     dx,es
                or      dx,dx
                je      @@29                    ; program jeszcze nie był zainstalowany
                mov     ax,3509h                ; deinstalacja
                int     21h
                mov     bx,es
                cmp     dx,bx
                jne     @@30                    ; nie można deinstalować
                mov     ax,352Fh
                int     21h
                mov     bx,es
                cmp     dx,bx
                jne     @@30                    ; nie można deinstalować
                mov     es,dx
                push    ds
                lds     dx,[es:old_09h-diff]    ; przywróć przerwanie 09h
                mov     ax,2509h
                int     21h
                lds     dx,[es:old_2Fh-diff]    ; przywróć przerwanie 2Fh
                mov     ax,252Fh
                int     21h
                pop     ds
                mov     [es:16h],ds             ; PSP adresu rodzicielskiego
                mov     [es:0Ch],cs             ; adres powrotu po funkcji 4Ch
                mov     [word es:0Ah],offset @@27       ; adres powrotu po funkcji 4Ch
                sub     sp,6                    ; FLAGS, CS, IP po funkcji INT (ignorowane)
                push    es
                push    ds
                push    bp
                push    di
                push    si
                push    dx
                push    cx
                push    bx
                push    ax
                mov     [30h],ss                ; wskaznik stosu
                mov     [2Eh],sp                ; pole nieudokumentowane
                mov     ah,50h
                mov     bx,es
                int     21h
                mov     ax,4C00h
                int     21h
        @@27:   mov     ah,9
                mov     dx,offset uninst_m      ; informacja o usunięciu
                int     21h
                xor     al,al
                jmp     exit                    ; program zdeinstalowany
        @@29:   mov     dx,offset not_inst_m
                mov     ah,9
                int     21h
                mov     al,5
                jmp     exit
        @@30:   mov     es,dx
                mov     [es:activ],0
                mov     dx,offset cant_uninst_m
                mov     ah,9
                int     21h
                mov     al,3
                jmp     exit

PROC            print_status
                USES    ax,dx
                mov     ax,es
                or      ax,ax
                mov     ah,9
                jnz     @@1
                mov     dx,offset not_installed_m
                jmp     @@3
        @@1:    mov     dx,offset prest_m
                int     21h
                mov     ah,[es:jaki_st]
                dec     ah
                mov     al,14
                mul     ah
                mov     dx,offset standardy
                add     dx,ax
                mov     ah,9
                int     21h
                cmp     [es:activ],0
                je      @@2
                mov     dx,offset activ_m
                jmp     @@3
        @@2:    mov     dx,offset deactiv_m
        @@3:    int     21h
                ret
ENDP

PROC            print_help
                USES    ax,dx
                mov     ah,9
                mov     dx,offset help_m
                int     21h
                ret
ENDP

PROC            convertax
                cmp     al,'A'
                jb      @@1
                cmp     al,'Z'
                ja      @@1
                add     al,'a'-'A'
        @@1:    cmp     ah,'A'
                jb      @@2
                cmp     ah,'Z'
                ja      @@2
                add     ah,'a'-'A'
        @@2:    ret
ENDP

DATASEG

prest_m         db      'Zainstalowano standard $'

standardy       db      'Mazovia',13,10,'$    '
                db      'CSK',13,10,'$        '
                db      'Cyfromat',13,10,'$   '
                db      'DHN',13,10,'$        '
                db      'Latin-2',13,10,'$    '
                db      'IEA Swierk',13,10,'$ '
                db      'LOGIC',13,10,'$      '
                db      'Microvex',13,10,'$   '
                db      'ISO Latin-2',13,10,'$'
                db      'Windows 3.1',13,10,'$'

activ_m         db      'Program jest aktywny',13,10,'$'

deactiv_m       db      'Program jest nieaktywny',13,10,'$'

uninst_m        db      'Program zostal usuniety z pamieci',13,10,'$'

copyright       db      'Polska klawiatura programisty wersja 2.02'
IFDEF __TYLDA__
                db      'T'
ENDIF
IFDEF __ALT__
IFDEF __CTRL__
                db      'C'
ELSE
                db      'A'
ENDIF
ENDIF
                db      13,10,'Copyright Tomasz Kepczynski, Lodz dn. ',??date,13,10,'$'

IFDEF __TYLDA__
ascii_codes     db      'A','C','E','L','N','O','S','X','Z'
                db      'a','c','e','l','n','o','s','x','z'
ENDIF
IFDEF __ALT__
IFDEF __CTRL__
ascii_codes     db      01,30,03,46,05,18,12,38,14,49,15,24,19,31,24,45,26,44
ELSE
ascii_codes     db      00,30,00,46,00,18,00,38,00,49,00,24,00,31,00,45,00,44
ENDIF
ENDIF


mazovia         db      143,149,144,156,165,163,152,160,161
                db      134,141,145,146,164,162,158,166,167

csk             db      128,129,130,131,132,133,134,136,135
                db      160,161,162,163,164,165,166,168,167

cyfromat        db      128,129,130,131,132,133,134,136,135
                db      144,145,146,147,148,149,150,152,151

dhn             db      128,129,130,131,132,133,134,136,135
                db      137,138,139,140,141,142,143,145,144

latin           db      164,143,168,157,227,224,151,141,189
                db      165,134,169,136,228,162,152,171,190

iea             db      143,128,144,156,165,153,235,157,146
                db      160,155,130,159,164,162,135,168,145

logic           db      128,129,130,131,132,133,134,135,136
                db      137,138,139,140,141,142,143,144,145

microvex        db      143,128,144,156,165,147,152,157,146
                db      160,155,130,159,164,162,135,168,145

iso             db      161,198,202,163,209,211,166,172,175
                db      177,230,234,179,241,243,182,188,191

win31           db      165,198,202,163,209,211,140,143,175
                db      185,230,234,179,241,243,156,159,191

not_inst_m      db      'Progam nie moze zostac odinstalowany, bo nie byl zainstalowany !!!',13,10,'$'

not_installed_m db      'Program nie jest zainstalowany',13,10,'$'

cant_uninst_m   db      'Odinstalowanie programu jest niemozliwe',13,10
                db      'Usun zainstalowane po tym programie rezydenty',13,10
                db      'Program zostal deaktywowany',13,10,'$'

help_m          db      'Program rezydentny umozliwiajacy wprowadzanie polskich znakow z klawiatury ',13,10
                db      'przy uzyciu '
IFDEF __TYLDA__
                db      'sekwencji lewy apostrof + znak',13,10
ENDIF
IFDEF __ALT__
IFDEF __CTRL__
                db      'kombinacji klawiszy prawy CTRL + znak',13,10
ELSE
                db      'kombinacji klawiszy prawy ALT + znak',13,10
ENDIF
ENDIF
                db      'Uzycie : POL_KLAW komenda',13,10
                db      'Komenda jest jednym z ponizszych slow :',13,10
                db      'mazovia    - zainstalowanie obslugi standardu Mazovia',13,10
                db      'csk        - zainstalowanie obslugi standardu CSK',13,10
                db      'cyfromat   - zainstalowanie obslugi standardu Cyfromat',13,10
                db      'dhn        - zainstalowanie obslugi standardu DHN',13,10
                db      'latin      - zainstalowanie obslugi standardu Latin - 2',13,10
                db      'iea        - zainstalowanie obslugi standardu IEA Swierk',13,10
                db      'logic      - zainstalowanie obslugi standardu LOGIC',13,10
                db      'microvex   - zainstalowanie obslugi standardu Microvex',13,10
                db      'iso        - zainstalowanie obslugi standardu ISO Latin - 2',13,10
                db      'win31      - zainstalowanie obslugi standardu Windows 3.1',13,10
                db      'help       - wyswietlenie tej informacji pomocniczej',13,10
                db      'status     - podanie statusu programu',13,10
                db      'odinstaluj - usuniecie programu z pamieci',13,10
                db      'remove     - j.w.',13,10
                db      '-          - deaktywacja czesci rezydentnej',13,10
                db      '+          - aktywacja czesci rezydentnej',13,10
                db      'Program wymaga podania jednej z powyzszych komend (wymagane sa dwie pierwsze',13,10
                db      'litery). Male i wielkie litery sa nierozroznialne.$'
ENDIF ; ??defined
ENDIF ; @Model ne 1

END
